import { Rule } from "./types";

export const PotentialBugsRuleList: Rule[] = [
    {
        id: "AvoidReferentialEquality",
        descEn: "Kotlin supports two types of equality: structural equality and referential equality. While there are use cases for both, checking for referential equality for some types (such as String or List) is likely not intentional and may cause unexpected results.",
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [
            {
                param: "forbiddenTypePatterns",
                descEn: "Specifies those types for which referential equality checks are considered a rule violation. The types are defined by a list of simple glob patterns (supporting * and ? wildcards) that match the fully qualified type name.",
                descCn: "",
                defaultValue: ['kotlin.String'],
            }
        ],
        url: "https://detekt.dev/docs/rules/potential-bugs#avoidreferentialequality",
    },
    {
        id: "CastToNullableType",
        descEn: "Disallow to cast to nullable types. There are cases where as String? is misused as safe cast (as? String). So if you want to prevent those cases, turn on this rule.",
        descCn: "",
        active: false,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#casttonullabletype",
    },
    {
        id: "Deprecation",
        descEn: "Deprecated elements are expected to be removed in the future. Alternatives should be found if possible.",
        descCn: "",
        active: false,
        debt: "20min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#deprecation",
    },
    {
        id: "DontDowncastCollectionTypes",
        descEn: "Down-casting immutable types from kotlin.collections should be discouraged. The result of the downcast is platform specific and can lead to unexpected crashes. Prefer to use instead the toMutable<Type>() functions.",
        descCn: "",
        active: false,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#dontdowncastcollectiontypes",
    },
    {
        id: "DoubleMutabilityForCollection",
        descEn: `Using var when declaring a mutable collection or value holder leads to double mutability. Consider instead declaring your variable with val or switching your declaration to use an immutable type.

        By default, the rule triggers on standard mutable collections, however it can be configured to trigger on other types of mutable value types, such as MutableState from Jetpack Compose.`,
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [
            {
                param: "mutableTypes",
                descEn: "Define a list of mutable types to trigger on when defined with var.",
                descCn: "",
                defaultValue: ['kotlin.collections.MutableList', 'kotlin.collections.MutableMap', 'kotlin.collections.MutableSet', 'java.util.ArrayList', 'java.util.LinkedHashSet', 'java.util.HashSet', 'java.util.LinkedHashMap', 'java.util.HashMap'],
            }
        ],
        url: "https://detekt.dev/docs/rules/potential-bugs#doublemutabilityforcollection",
    },
    {
        id: "ElseCaseInsteadOfExhaustiveWhen",
        descEn: `This rule reports when expressions that contain an else case even though they have an exhaustive set of cases.

        This occurs when the subject of the when expression is either an enum class, sealed class or of type boolean. Using else cases for these expressions can lead to unintended behavior when adding new enum types, sealed subtypes or changing the nullability of a boolean, since this will be implicitly handled by the else case.`,
        descCn: "",
        active: false,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#elsecaseinsteadofexhaustivewhen",
    },
    {
        id: "EqualsAlwaysReturnsTrueOrFalse",
        descEn: `Reports equals() methods which will always return true or false.

        Equals methods should always report if some other object is equal to the current object. See the Kotlin documentation for Any.equals(other: Any?)`,
        descCn: "",
        active: true,
        debt: "20min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#equalsalwaysreturnstrueorfalse",
    },
    {
        id: "EqualsWithHashCodeExist",
        descEn: `When a class overrides the equals() method it should also override the hashCode() method.

        All hash-based collections depend on objects meeting the equals-contract. Two equal objects must produce the same hashcode. When inheriting equals or hashcode, override the inherited and call the super method for clarification.`,
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#equalswithhashcodeexist",
    },
    {
        id: "ExitOutsideMain",
        descEn: "Flags use of System.exit() and Kotlin's exitProcess() when used outside the main function. This makes code more difficult to test, causes unexpected behaviour on Android, and is a poor way to signal a failure in the program. In almost all cases it is more appropriate to throw an exception.",
        descCn: "",
        active: false,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#exitoutsidemain",
    },
    {
        id: "ExplicitGarbageCollectionCall",
        descEn: "Reports all calls to explicitly trigger the Garbage Collector. Code should work independently of the garbage collector and should not require the GC to be triggered in certain points in time.",
        descCn: "",
        active: true,
        debt: "20min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#explicitgarbagecollectioncall",
    },
    {
        id: "HasPlatformType",
        descEn: "Platform types must be declared explicitly in public APIs to prevent unexpected errors.",
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#hasplatformtype",
    },
    {
        id: "IgnoredReturnValue",
        descEn: "This rule warns on instances where a function, annotated with either @CheckReturnValue or @CheckResult, returns a value but that value is not used in any way. The Kotlin compiler gives no warning for this scenario normally so that's the rationale behind this rule.",
        descCn: "",
        active: true,
        debt: "20min",
        paramList: [
            {
                param: "restrictToConfig",
                descEn: "If the rule should check only methods matching to configuration, or all methods",
                descCn: "",
                defaultValue: true,
            },
            {
                param: "returnValueAnnotations",
                descEn: "List of glob patterns to be used as inspection annotation",
                descCn: "",
                defaultValue: ['*.CheckResult', '*.CheckReturnValue'],
            },
            {
                param: "ignoreReturnValueAnnotations",
                descEn: "Annotations to skip this inspection",
                descCn: "",
                defaultValue: ['*.CanIgnoreReturnValue'],
            },
            {
                param: "returnValueTypes",
                descEn: "List of return types that should not be ignored",
                descCn: "",
                defaultValue: ['kotlin.sequences.Sequence', 'kotlinx.coroutines.flow.*Flow', 'java.util.stream.*Stream'],
            },
            {
                param: "ignoreFunctionCall",
                descEn: "List of function signatures which should be ignored by this rule. Specifying fully-qualified function signature with name only (i.e. java.time.LocalDate.now) will ignore all function calls matching the name. Specifying fully-qualified function signature with parameters (i.e. java.time.LocalDate.now(java.time.Clock)) will ignore only function calls matching the name and parameters exactly.",
                descCn: "",
                defaultValue: [],
            },
        ],
        url: "https://detekt.dev/docs/rules/potential-bugs#ignoredreturnvalue",
    },
    {
        id: "ImplicitDefaultLocale",
        descEn: `Prefer passing [java.util.Locale] explicitly than using implicit default value when formatting strings or performing a case conversion.

        The default locale is almost always inappropriate for machine-readable text like HTTP headers. For example, if locale with tag ar-SA-u-nu-arab is a current default then %d placeholders will be evaluated to a number consisting of Eastern-Arabic (non-ASCII) digits. [java.util.Locale.US] is recommended for machine-readable output.`,
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#implicitdefaultlocale",
    },
    {
        id: "ImplicitUnitReturnType",
        descEn: "Functions using expression statements have an implicit return type. Changing the type of the expression accidentally, changes the functions return type. This may lead to backward incompatibility. Use a block statement to make clear this function will never return a value.",
        descCn: "",
        active: false,
        debt: "5min",
        paramList: [
            {
                param: "allowExplicitReturnType",
                descEn: "if functions with explicit 'Unit' return type should be allowed",
                descCn: "",
                defaultValue: true,
            }
        ],
        url: "https://detekt.dev/docs/rules/potential-bugs#implicitunitreturntype",
    },
    {
        id: "InvalidRange",
        descEn: "Reports ranges which are empty. This might be a bug if it is used for instance as a loop condition. This loop will never be triggered then. This might be due to invalid ranges like (10..9) which will cause the loop to never be entered.",
        descCn: "",
        active: true,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#invalidrange",
    },
    {
        id: "IteratorHasNextCallsNextMethod",
        descEn: "Verifies implementations of the Iterator interface. The hasNext() method of an Iterator implementation should not have any side effects. This rule reports implementations that call the next() method of the Iterator inside the hasNext() method.",
        descCn: "",
        active: true,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#iteratorhasnextcallsnextmethod",
    },
    {
        id: "IteratorNotThrowingNoSuchElementException",
        descEn: "Reports implementations of the Iterator interface which do not throw a NoSuchElementException in the implementation of the next() method. When there are no more elements to return an Iterator should throw a NoSuchElementException.",
        descCn: "",
        active: true,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#iteratornotthrowingnosuchelementexception",
    },
    {
        id: "LateinitUsage",
        descEn: `Turn on this rule to flag usages of the lateinit modifier.

        Using lateinit for property initialization can be error-prone and the actual initialization is not guaranteed. Try using constructor injection or delegation to initialize properties.`,
        descCn: "",
        active: false,
        debt: "20min",
        paramList: [
            {
                param: "ignoreOnClassesPattern",
                descEn: "Allows you to disable the rule for a list of classes",
                descCn: "",
                defaultValue: "",
            }
        ],
        url: "https://detekt.dev/docs/rules/potential-bugs#lateinitusage",
    },
    {
        id: "MapGetWithNotNullAssertionOperator",
        descEn: "Reports calls of the map access methods map[] or map.get() with a not-null assertion operator !!. This may result in a NullPointerException. Preferred access methods are map[] without !!, map.getValue(), map.getOrDefault() or map.getOrElse().",
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#mapgetwithnotnullassertionoperator",
    },
    {
        id: "MissingPackageDeclaration",
        descEn: "Reports when the package declaration is missing.",
        descCn: "",
        active: false,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#missingpackagedeclaration",
    },
    {
        id: "NullCheckOnMutableProperty",
        descEn: "Reports null-checks on mutable properties, as these properties' value can be changed - and thus make the null-check invalid - after the execution of the if-statement.",
        descCn: "",
        active: false,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#nullcheckonmutableproperty",
    },
    {
        id: "NullableToStringCall",
        descEn: `Turn on this rule to flag 'toString' calls with a nullable receiver that may return the string "null".`,
        descCn: "",
        active: false,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#nullabletostringcall",
    },
    {
        id: "UnconditionalJumpStatementInLoop",
        descEn: "Reports loops which contain jump statements that jump regardless of any conditions. This implies that the loop is only executed once and thus could be rewritten without a loop altogether.",
        descCn: "",
        active: false,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unconditionaljumpstatementinloop",
    },
    {
        id: "UnnecessaryNotNullCheck",
        descEn: "Reports unnecessary not-null checks with requireNotNull or checkNotNull that can be removed by the user.",
        descCn: "",
        active: false,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unnecessarynotnullcheck",
    },
    {
        id: "UnnecessaryNotNullOperator",
        descEn: "Reports unnecessary not-null operator usage (!!) that can be removed by the user.",
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unnecessarynotnulloperator",
    },
    {
        id: "UnnecessarySafeCall",
        descEn: "Reports unnecessary safe call operators (?.) that can be removed by the user.",
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unnecessarysafecall",
    },
    {
        id: "UnreachableCatchBlock",
        descEn: "Reports unreachable catch blocks. Catch blocks can be unreachable if the exception has already been caught in the block above.",
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unreachablecatchblock",
    },
    {
        id: "UnreachableCode",
        descEn: "Reports unreachable code. Code can be unreachable because it is behind return, throw, continue or break expressions. This unreachable code should be removed as it serves no purpose.",
        descCn: "",
        active: true,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unreachablecode",
    },
    {
        id: "UnsafeCallOnNullableType",
        descEn: "Reports unsafe calls on nullable types. These calls will throw a NullPointerException in case the nullable value is null. Kotlin provides many ways to work with nullable types to increase null safety. Guard the code appropriately to prevent NullPointerExceptions.",
        descCn: "",
        active: true,
        debt: "20min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unsafecallonnullabletype",
    },
    {
        id: "UnsafeCast",
        descEn: "Reports casts that will never succeed.",
        descCn: "",
        active: true,
        debt: "20min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unsafecast",
    },
    {
        id: "UnusedUnaryOperator",
        descEn: "This rule detects unused unary operators.",
        descCn: "",
        active: true,
        debt: "5min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#unusedunaryoperator",
    },
    {
        id: "UselessPostfixExpression",
        descEn: "This rule reports postfix expressions (++, --) which are unused and thus unnecessary. This leads to confusion as a reader of the code might think the value will be incremented/decremented. However, the value is replaced with the original value which might lead to bugs.",
        descCn: "",
        active: true,
        debt: "20min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#uselesspostfixexpression",
    },
    {
        id: "WrongEqualsTypeParameter",
        descEn: "Reports equals() methods which take in a wrongly typed parameter. Correct implementations of the equals() method should only take in a parameter of type Any?",
        descCn: "",
        active: true,
        debt: "10min",
        paramList: [],
        url: "https://detekt.dev/docs/rules/potential-bugs#wrongequalstypeparameter",
    },
];